﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ParasiTracer
{
    class ThreadInfo 
    {
        Thread      _self   = null;
        int         _depth  = 0;
        Stack<int>  _calls  = new Stack<int>();
        List<int>   _paramPointer = new List<int>();

        const int BOOL_PARAM    = 1;
        const int CHAR_PARAM    = 2;
        const int SBYTE_PARAM   = 3;
        const int BYTE_PARAM    = 4;
        const int INT16_PARAM   = 5;
        const int UINT16_PARAM  = 6;
        const int INT32_PARAM   = 7;
        const int UINT32_PARAM  = 8;
        const int INT64_PARAM   = 9;
        const int UINT64_PARAM  = 10;
        const int SINGLE_PARAM  = 11;
        const int DOUBLE_PARAM  = 12;
        const int STRING_PARAM  = 13;
        const int INTPTR_PARAM  = 14;
        const int UINTPTR_PARAM = 15;
        const int OBJECT_PARAM  = 16;

        List<bool>  _boolParams     = new List<bool>    (); //1
        List<char>  _charParams     = new List<char>    (); //2
        List<sbyte> _sbyteParams    = new List<sbyte>   (); //3
        List<byte>  _byteParams     = new List<byte>    (); //4
        List<short> _int16Params    = new List<short>   (); //5
        List<ushort>_uint16Params   = new List<ushort>  (); //6
        List<int>   _int32Params    = new List<int>     (); //7
        List<uint>  _uint32Params   = new List<uint>    (); //8
        List<long>  _int64Params    = new List<long>    (); //9
        List<ulong> _uint64Params   = new List<ulong>   (); //10
        List<float> _singleParams   = new List<float>   (); //11
        List<double>_doubleParams   = new List<double>  (); //12
        List<string>_stringParams   = new List<string>  (); //13
        List<IntPtr>_intptrParams   = new List<IntPtr>  (); //14
        List<UIntPtr>_uintptrParams = new List<UIntPtr> (); //15
        List<object>_objectParams   = new List<object>  (); //16

        public ThreadInfo ()
        {
            //
        }

        void pushBoolParam (bool param)
        {
            _paramPointer.Add(BOOL_PARAM);
            _boolParams.Add(param);
        }

        void pushCharParam(char param)
        {
            _paramPointer.Add(CHAR_PARAM);
            _charParams.Add(param);
        }

        void pushSByteParam(sbyte param)
        {
            _paramPointer.Add(SBYTE_PARAM);
            _sbyteParams.Add(param);
        }

        void pushByteParam(byte param)
        {
            _paramPointer.Add(BYTE_PARAM);
            _byteParams.Add(param);
        }

        void pushInt16Param(short param)
        {

        }

        public void push(int funcId)
        {
            if (_depth == 0)
            {
                _self = Thread.CurrentThread;
                // evento beginThread
            }

            _calls.Push(funcId);
            _depth++;
        }

        public int pop()
        {
            int popedValue = _calls.Pop();
            _depth--;

            if (_depth == 0)
            {
                _self = null;
                // evento endThread
            }

            return popedValue;
        }

        public int depth()
        {
            return _depth;
        }

        public int[] stackTrace()
        {
            return _calls.ToArray();
        }

        public Thread self
        {
            get
            {
                return _self;
            }
        }
    }
}
